#include "TestManager.h"

#include <cassert>

TestManager::TestManager()
	:  m_updateEnabled(false),
	   m_currentTest(0)
{
	SetSlowMotion(1.0f);
	m_lastUpdateTime = m_clock.GetElapsedTime();
	SetTestUpdateEnabled(true);
}

TestManager::~TestManager()
{
	ClearTests();
}

void TestManager::AddTest(Test* i_test)
{
	m_tests.push_back(i_test);
}

void TestManager::ClearTests()
{
	for(std::vector<Test*>::iterator i = m_tests.begin(); i != m_tests.end(); ++i)
		delete *i;
	m_tests.clear();
}

bool TestManager::IsTestUpdateEnabled() const
{
	return m_updateEnabled;
}

void TestManager::SetTestUpdateEnabled(bool enabled)
{
	m_updateEnabled = enabled;
	m_lastUpdateTime = m_clock.GetElapsedTime();
}

float TestManager::GetSlowMotion() const
{
	return m_slowMotionFactor;
}

void TestManager::SetSlowMotion(const float i_slowMotionTime)
{
	m_slowMotionFactor = i_slowMotionTime;
}

void TestManager::SetRenderer(Renderer* renderer)
{
	m_renderer = renderer;
}

void TestManager::OnKeyUp(sf::Key::Code keyCode)
{
	if (keyCode == sf::Key::Space)
	{
		SetTestUpdateEnabled(!m_updateEnabled);
	}
	else if(keyCode == sf::Key::RControl)
	{
		if(!m_updateEnabled && m_currentTest)
			m_currentTest->Update(1.0f/60.0f); // a little bit hardcoded :)
	}
	else if (keyCode == sf::Key::I)
	{
		RestartCurrentTest();
	}
	else if (keyCode >= sf::Key::Num1 && keyCode <= sf::Key::Num9)
	{
		int testNumber = keyCode - '1';
		StartTest(testNumber);
	}
	else if (keyCode == sf::Key::A)
	{
		SetSlowMotion(m_slowMotionFactor * 2.0f);
	}
	else if (keyCode == sf::Key::Z)
	{
		SetSlowMotion(m_slowMotionFactor / 2.0f);
	}
	else
	{
		if(m_currentTest)
			m_currentTest->OnKeyPressed(keyCode);
	}
}

void TestManager::OnIdle()
{
	if (m_updateEnabled && m_currentTest)
	{
		const float currentTime = m_clock.GetElapsedTime();
		const float elapsedTime = (currentTime - m_lastUpdateTime) * m_slowMotionFactor;
		
		m_currentTest->Update(elapsedTime);
		
		m_lastUpdateTime = currentTime;
	}
	m_renderer->Render();
}

void TestManager::OnPaint()
{
	if (m_currentTest)
		m_currentTest->Render(*m_renderer);

	DrawInstructions();
}

void TestManager::StartTest(UInt testNumber)
{
	if (testNumber < m_tests.size())
	{
		m_currentTest = m_tests[testNumber];
		m_currentTest->Init();
	}
}

void TestManager::RestartCurrentTest()
{
	if(m_currentTest)
		m_currentTest->Init();
}

void TestManager::DrawInstructions()
{
	m_renderer->RenderTextLine("space: pause/resume");
	m_renderer->RenderTextLine("I: reinitialize the simulation");
	m_renderer->RenderTextLine("A/Z: change simulation speed");
}
